<template>
  <div ref="shadowRef" @mousedown="handleMouseDown"/>
</template>

<script>
export default {
  props: {
    cdata: {
      type: Object,
      default() {
        return {};
      }
    },
    range: {
      type: Number,
      default: 0
    },
    list: {
      type: Array,
      default() {
        return () => [];
      }
    },
    isLeft: Boolean,
    isTop: Boolean,
    lockX: Boolean,
    lockY: Boolean
  },
  data() {
    return {
      disX: 0,
      disY: 0,
      iParentTop: 0,
      iParentLeft: 0,
      iParentWidth: 0,
      iParentHeight: 0
    };
  },
  methods: {
    getPosition() {
      let target = this.$refs.shadowRef.parentElement;
      return [...this.list].filter((v, idx) => idx !== this.range).map(item => {
        const validX = (target.offsetLeft + target.offsetWidth) >= item.left && target.offsetLeft <= (item.left + item.width);
        const validY = (target.offsetTop + target.offsetHeight) >= item.top && target.offsetTop <= (item.top + item.height);
        // 左侧
        item.isLeft = target.offsetLeft >= (item.left + item.width) && validY;
        // 右侧
        item.isRight = target.offsetLeft <= (item.left - target.offsetWidth) && validY;
        // 上侧
        item.isTop = target.offsetTop >= (item.top + item.height) && validX;
        // 下侧
        item.isBottom = target.offsetTop <= (item.top - target.offsetHeight) && validX;
        return item;
      });
    },
    handleMouseDown(event) {
      event.stopPropagation();
      const targetEl = this.$refs.shadowRef;
      const parentEl = targetEl.parentElement;
      this.disX = event.clientX - this.$refs.shadowRef.offsetLeft;
      this.disY = event.clientY - this.$refs.shadowRef.offsetTop;
      this.iParentTop = parentEl.offsetTop;
      this.iParentLeft = parentEl.offsetLeft;
      this.iParentWidth = parentEl.offsetWidth;
      this.iParentHeight = parentEl.offsetHeight;
      this.$nextTick(() => {
        document.onmousemove = this.handleMouseMove;
        document.onmouseup = this.handleMouseUp;
        document.onmousecancel = this.handleMouseUp;
      });
    },
    handleMouseMove(event) {
      event.stopPropagation();
      const dragMinWidth = 50;
      const dragMinHeight = 50;
      const targetEl = this.$refs.shadowRef;
      if (!targetEl) return;
      const parentEl = targetEl.parentElement;
      const wrapperEl = this.$parent.$refs.hotRef.parentElement;
      let iL = event.clientX - this.disX;
      let iT = event.clientY - this.disY;
      const maxW = wrapperEl.offsetWidth - parentEl.offsetLeft - 2;
      const maxH = wrapperEl.offsetHeight - parentEl.offsetTop - 2;
      let iW = this.isLeft ? this.iParentWidth - iL : targetEl.offsetWidth + iL;
      let iH = this.isTop ? this.iParentHeight - iT : targetEl.offsetHeight + iT;
      iW = Math.max(iW, dragMinWidth);
      iW = Math.min(iW, maxW);
      iH = Math.max(iH, dragMinHeight);
      iH = Math.min(iH, maxH);
      let finalLeft = this.iParentLeft + iL;
      let finalTop = this.iParentTop + iT;
      if (this.isLeft) {
        finalLeft = Math.max(0, finalLeft);
        iW = Math.min(iW, this.iParentWidth + this.iParentLeft);
      }
      if (this.isTop) {
        finalTop = Math.max(0, finalTop);
        iH = Math.min(iH, this.iParentHeight + this.iParentTop);
      }
      const positions = this.getPosition();
      positions.map(item => {
        // 左侧
        if (this.isLeft && item.isLeft) {
          finalLeft = Math.max(finalLeft, item.left + item.width);
          iW = this.iParentWidth - finalLeft + this.iParentLeft;
        }
        // 右侧
        if (item.isRight) {
          iW = Math.min(iW, item.left - (this.isLeft ? finalLeft : parentEl.offsetLeft));
        }
        // 上侧
        if (this.isTop && item.isTop) {
          finalTop = Math.max(finalTop, item.top + item.height);
          iH = this.iParentHeight - finalTop + this.iParentTop;
        }
        // 下侧
        if (item.isBottom) {
          iH = Math.min(iH, item.top - (this.isTop ? finalTop : parentEl.offsetTop));
        }
      });
      if (this.isLeft) parentEl.style.left = finalLeft + 'px';
      if (this.isTop) parentEl.style.top = finalTop + 'px';
      if (!this.lockX) parentEl.style.width = iW + 'px';
      if (!this.lockY) parentEl.style.height = iH + 'px';
      if ((this.isLeft && iW === dragMinWidth) || (this.isTop && iH === dragMinHeight)) document.onmousemove = null;
    },
    handleMouseUp(event) {
      event && event.stopPropagation();
      this.$parent.handleMouseUp();
      document.onmousemove = null;
      document.onmouseup = null;
      document.onmousecancel = null;
    }
  }
};
</script>

<style lang="less">

</style>
